﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Security;

namespace SPPlus.CustomField.JqueryScript
{
    public class JqueryScriptField : SPFieldMultiLineText
    {

        const string PROPERTYNAME = "FieldCustomProperty";

        #region Properties
        /// <summary>
        /// Unique code to identifiy this instance in order to allow the use of the static value stored in the dictionary object.
        /// If multiple users are editing instances of this field simultaneously, one static instance of the dictionary will exist, 
        /// but each editor instance will have a different ContextID and hence a different dictionery entry
        /// </summary>
        public int ContextId
        { get { return SPContext.Current.GetHashCode(); } }
        /// <summary>
        /// Dictionery used to temporarily cache the property value in the case where a new field is being created.
        /// This is necessary as the Update method call does not have access to the selected values in the editor for new fields.
        /// (see http://www.windows-tech.info/6/fa4c9cbcadcdd8fb.php - "Custom Field Type Properties" for details)
        /// </summary>
        private static Dictionary<int, string> cachedProperty = new Dictionary<int, string>();
        /// <summary>
        /// Private field storing the custom property value
        /// </summary>
        private string customProperty;
        /// <summary>
        /// Public access to the custom property
        /// </summary>
        public string CustomProperty
        {
            get { return cachedProperty.ContainsKey(ContextId) ? cachedProperty[ContextId] : customProperty; }
            set { customProperty = value; }
        }
        #endregion

        #region Constructors
        public JqueryScriptField(SPFieldCollection fields, string fieldName)
            : base(fields, fieldName)
        {
            Init();
        }

        public JqueryScriptField(SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName)
        {
            Init();
        }
        /// <summary>
        /// Retrieve the stored custom property from the SchemaXml of the field instance
        /// </summary>
        private void Init()
        {
            customProperty = (string)GetCustomProperty(PROPERTYNAME);
        }
        #endregion

        #region Field overrides
        public override BaseFieldControl FieldRenderingControl
        {
            [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
            get
            {
                JqueryScriptFieldControl fieldControl = new JqueryScriptFieldControl();
                fieldControl.FieldName = this.InternalName;
                fieldControl.RenderScript(CustomProperty);

                return fieldControl;
            }
        }
        public override string GetValidatedString(object value)
        {
            return base.GetValidatedString(value);
        }
        #endregion

        #region Custom property handling
        /// <summary>
        /// Cache the custom property for a new field definition
        /// </summary>
        /// <param name="value">The script value to cache</param>
        public void CacheCustomProperty(string value)
        {
            cachedProperty[ContextId] = value;
        }
        public override void Update()
        {
            SetCustomProperty(PROPERTYNAME, CustomProperty);

            //if (base.ShowInDisplayForm != false)
            //{
            //    base.ShowInDisplayForm = false;
            //    base.ShowInViewForms = false;
            //}
            base.Update();

            if (cachedProperty.ContainsKey(ContextId))
                cachedProperty.Remove(ContextId);
        }
        public override void OnAdded(SPAddFieldOptions op)
        {
            base.OnAdded(op);
            Update();
        }
        #endregion

    }
}
